package joe;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface Input {
	void init();

	void destroy();

	/**
	 * @return 0:released 1:pressing
	 */
	int getKeyboardState(int keyCode);

	/**
	 * @return 0:released 1:pressing
	 */
	int getMouseState(int keyCode);

	/**
	 * @return [0, WindowWidth)
	 */
	int getMouseX();

	/**
	 * @return [0, WindowHeight) 0 is top
	 */
	int getMouseY();

	/**
	 * @param index device index (base-0)
	 * @param axes  axis values [-1,1]
	 * @return button pressed bits (bitN:buttonN). -1:not connected
	 */
	int getGamepadStates(int index, float @Nullable [] axes);

	void poll();

	interface EventHandler {
		int KEY_PRESS = 0;
		int KEY_RELEASE = 1;
		int MOUSE_MOVE = 10;      // x=[0,w),y=[0,h). (0,0) is top-left; keyCode=0
		int MOUSE_PRESS = 11;     // same as above with keyCode
		int MOUSE_RELEASE = 12;   // same as above with keyCode
		int MOUSE_SCROLL = 13;    // y>0: wheel up; y<0: wheel down; keyCode=0
		int GAMEPAD_PRESS = 20;   // high 16-bit in keyCode is device index (base-0)
		int GAMEPAD_RELEASE = 21; // same as above

		/**
		 * @param event   see above int enum
		 * @param keyCode defined by implement
		 */
		boolean onEvent(int event, int keyCode, int x, int y);
	}

	void fireEvent(int event, int keyCode, int x, int y);

	void addEventListener(@NotNull EventHandler handler);

	void removeEventListener(@NotNull EventHandler handler);

	void addEventHandler(@NotNull EventHandler handler);

	void removeEventHandler(@NotNull EventHandler handler);
}
